package manager

import (
	"fmt"
	"github.com/casbin/casbin/v2"
	gormadapter "github.com/casbin/gorm-adapter/v3"
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"net/http"
	"server/common"
	"server/internal/model"
	"server/pkg/app"
	"server/pkg/setting"
)

var Enforcer *casbin.Enforcer

func InitCasbin(databaseSetting *setting.DatabaseSettingS) {
	s := "%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&loc=Local"
	DSN := fmt.Sprintf(s,
		databaseSetting.UserName,
		databaseSetting.Password,
		databaseSetting.Host,
		"casbin",
		databaseSetting.Charset,
		databaseSetting.ParseTime,
	)
	var err error
	common.CasbinDB, err = gorm.Open(mysql.New(mysql.Config{
		DSN:                       DSN,   // DSN data source name
		DefaultStringSize:         256,   // string 类型字段的默认长度
		DisableDatetimePrecision:  true,  // 禁用 datetime 精度，MySQL 5.6 之前的数据库不支持
		DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式，MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
		DontSupportRenameColumn:   true,  // 用 `change` 重命名列，MySQL 8 之前的数据库和 MariaDB 不支持重命名列
		SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
	}), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	// 创建 Casbin 适配器
	adapter, err := gormadapter.NewAdapterByDB(common.CasbinDB)
	if err != nil {
		panic(err)
	}

	// 初始化 Casbin
	Enforcer, err = casbin.NewEnforcer("configs/casbin.conf", adapter)
	if err != nil {
		panic(err)
	}

	// 加载策略（首次运行需要初始化策略）
	initPolicy()

	// 自动加载策略变更
	Enforcer.EnableAutoSave(true)
}

// 初始化策略（首次运行使用）
func initPolicy() {
	// 清除旧策略
	Enforcer.ClearPolicy()

	// 添加策略
	Enforcer.AddPolicy("superadmin", "*", "*")

	Enforcer.LoadPolicy()

	//enforcer.AddPolicy("admin", "/admin/*", "*")
	//enforcer.AddPolicy("user", "/api/user", "GET")
	//enforcer.AddPolicy("user", "/api/public", "*")
	//
	//// 添加角色继承
	//enforcer.AddGroupingPolicy("alice", "admin")
	//enforcer.AddGroupingPolicy("bob", "user")
}

// 模拟用户角色查询（实际应从数据库获取）
func GetUserRole(username string) string {
	u := &model.User{BaseUser: model.BaseUser{Name: username}}
	u.Info()
	return string(u.Role)
}

// 添加策略
func AddPolicy(c *gin.Context) {
	var policy struct {
		Sub string `json:"sub"`
		Obj string `json:"obj"`
		Act string `json:"act"`
	}

	if err := c.ShouldBindJSON(&policy); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}

	added, err := Enforcer.AddPolicy(policy.Sub, policy.Obj, policy.Act)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"result": added})
}

// 查询策略
func GetPolicy(c *gin.Context) {
	casbins := &CasbinRule{}
	pages := &app.Page{}
	pages.Info(c)
	casbin_list, total := casbins.List(pages)
	c.JSON(http.StatusOK, gin.H{
		"total": total,
		"data":  casbin_list,
	})
}

func DeletePolicy(c *gin.Context) {

}

func ModifyPolicy(c *gin.Context) {}
